1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
import { Page, PipelineStageError } from "corvos";
import { strapiLoader } from "$/deps/strapi.tsx";
import { releaseStrapiSchema } from "$/schemas/releases.ts";
import { BaseLayout } from "$/ui/base/BaseLayout.tsx";
import { ReleaseCard } from "$/ui/components/ReleaseCard.tsx";
import { SiteHeader } from "$/ui/components/SiteHeader.tsx";
import { CardList } from "$/ui/layouts/CardList.tsx";
import { Container } from "$/ui/layouts/Container.tsx";
import { HList } from "$/ui/layouts/HList.tsx";
import { ActionButton } from "$/ui/objects/ActionButton.tsx";
import { Badge } from "$/ui/objects/Badge.tsx";
import { Body } from "$/ui/objects/Body.tsx";
import { Divider } from "$/ui/objects/Divider.tsx";
import { Heading } from "$/ui/objects/Heading.tsx";
import { Icon } from "$/ui/objects/Icon.tsx";
import site from "@/corvos.config.ts";
export const pages = site.$.pageGenerator(async function* () {
for await (const item of strapiLoader.loadCollection("corvos-releases", releaseStrapiSchema, {
"populate[0]": "files",
"sort[0]": "date:desc",
})) {
if (item instanceof PipelineStageError) {
yield item;
continue;
}
yield new Page(".strapi", item.notes ?? [], {
...item,
title: `Corvos ${item.version}`,
type: "release" as const,
});
}
});
export const template = site.$.template({ type: "release" }, (page, pages) => {
const query = site.$.query(pages);
const feed = query.type(".rss").match({ type: "releases" }).one();
const prev = query.type(".html").match({ type: "release" }).prev(page);
const next = query.type(".html").match({ type: "release" }).next(page);
return (
<BaseLayout page={page}>
<SiteHeader
mode="compact"
url={page.url}
end={
<div class="l-media__block">
<ActionButton
align-block
class="u-mbs-0"
href={feed.url}
icon={<Icon icon="rss-simple" variant="bold" />}
level="quiet"
pill
title="RSS Feed"
/>
</div>
}
>
<div class="l-media__block l-media__block--main">
<Heading class="u-mbs-0 u-elp">{page.data.title}</Heading>
</div>
</SiteHeader>
<Container as="main" class="u-mbs-neutralize h-entry" fixed="150" pad-block pad-inline>
<HList aria-label="Categories">
<li>
<Badge as="strong" pill selected>
<time class="dt-published" datetime={page.data.date.toISOString()}>
{page.data.date.toLocaleDateString(undefined, {
day: "numeric",
month: "short",
year: "numeric",
})}
</time>
</Badge>
</li>
</HList>
<Heading as="h1" class="u-mbs-200 p-name" display highlight level="xxl">
{page.data.title}
</Heading>
<Body class="e-content">{{ __html: page.content }}</Body>
</Container>
<Divider level="faint" />
<Container as="footer" class="u-mbs-neutralize" fixed="150" pad-block pad-inline>
<CardList layout="grid">
{prev && <ReleaseCard heading-level="h2" page={prev} list />}
{next && <ReleaseCard heading-level="h2" page={next} list />}
</CardList>
</Container>
</BaseLayout>
);
});
|